package com.itheima.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import cn.hutool.jwt.JWTUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.cammon.CommonResult;
import com.itheima.cammon.PageInof;
import com.itheima.mapper.EmployeeMapper;
import com.itheima.pojo.Employee;
import com.itheima.service.EmployeeService;
import com.itheima.vo.EmployeeVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author 王同学
 */
@Service
@Slf4j
public class EmployeeServiceimpl implements EmployeeService {
    @Autowired
    EmployeeMapper employeeMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public EmployeeVO login(String username, String password) {
        //先加密再查询  生成解密
        Digester md5 = new Digester(DigestAlgorithm.MD5);
        String s = md5.digestHex(password);
        //这边去做查询
        Employee res = employeeMapper.SelectByUsernameandPassword(username, s);
        if (res==null){
            return null;
        }

        //token 唯一
        //用时间戳加上字符串返回上去  生成token
       // String token =System.currentTimeMillis()+ res.getId();
        //生成token方式二 用糊涂集成的jwt生成
        String key="&#&#355wwfsdfhreszdxjhbciklwshjgdrn#&*%&%$%^";
        //一个是string类型 另一个是obj类型
        Map<String,Object> map=new HashMap<>();//里面不写默认是15也就是16的空间从0开始
        map.put("username", res.getUsername());
        String token =  JWTUtil.createToken(map,key.getBytes());

        //存入redis数据库
        redisTemplate.opsForValue().set("employee_token:"+token, JSON.toJSONString(res));
        EmployeeVO employeeVO=new EmployeeVO();

        //来源  目标 复制一份给vo 给前端看
        BeanUtils.copyProperties(res,employeeVO);
        //调用mapper层的方法来去修改token 根据id把token存进去
       employeeMapper.updateToken(token,res.getId());

        //把token写到vo里面让前端调用数据库对比
        employeeVO.setToken(token);
        return employeeVO;
    }

    @Override
    public void clearToken(String token) {
        //调用mapper层的方法 找token
        Employee emp = employeeMapper.getbyToken(token);
        //通过id去删除token
        employeeMapper.clearToken(emp.getId());

    }

    @Override
    public EmployeeVO getById(String id) {
        Employee employee = employeeMapper.getById(id);
        EmployeeVO employeeVO=new EmployeeVO();
        //如果找到了这个id 那么把他复制一份给vo 然后拿给前端
                             //这个的要复制的对象源， 后面这个是复制给他的
        BeanUtils.copyProperties(employee,employeeVO);
        return employeeVO;
    }
        @Override
    public PageInof<Employee> page(String name,Integer page,Integer PageSize){
        //分页查询的响应结果
        //先new一下调用
        PageInof pageInof=new PageInof<Employee>();
        //页码长度公式
        Integer start=(page-1)*PageSize;
        List<Employee> emp = employeeMapper.page(name, start, PageSize);
        pageInof.setRecords(emp);
        pageInof.setSize(PageSize);
        pageInof.setCurrent(page);
        //查询总条数 然后把总条数写进去 再返回哪个类
        long count = employeeMapper.countEployee(name);
        pageInof.setTotal(count);

        return pageInof;
    }

    //新增员工
    @Override
    public CommonResult add(Employee employee){
        //password默认要给他设置成123456  雪花id md5加密 if判空判null 判重复
        String ID = IdUtil.getSnowflakeNextIdStr();
        employee.setId(ID);
        /*姓名可以重复，身份证不能重复*/
        Employee res = finByIdNumber(employee.getIdNumber());
        if (res!=null){
            log.info("身份证重复了");
            return CommonResult.error("身份证重复了");
        }
        // TODO: 2022/11/24   待开发1，姓名可以重复，身份证不能重复、用户名不能重复

        /*用户名可以为空*/
        if (employee.getUsername()==null||employee.getUsername()==""){
            //生成随机数 如果没有用户名，那我们给他加一个
            //生成随机验证码admin
            String number = UUID
                    .randomUUID()
                    .toString()
                    .replace("-", "")
                    .toUpperCase().substring(0, 6);
            //把所有的字母转换成小写
            String res2 = number.toLowerCase();
            //设置要修改的地方
            employee.setUsername("新用户"+res2);
        }

        if (employee.getPassword()==null||employee.getPassword()==""){
            //如果为空。那么就贴心的给他加上密码
            employee.setPassword("123456");
        }
      /*  // TODO: 2022/11/23 这波要用equal判断，这边一个小失误
        if (employee.getSex().equals("1")){
            employee.setSex("男");
        }
        else {
            employee.setSex("女");
        }*/

        //调用md5加密
        Digester md5 = new Digester(DigestAlgorithm.MD5);
        String pass = md5.digestHex(employee.getPassword());
        employee.setPassword(pass);
        //加到sql里面
        employeeMapper.add(employee);
        return CommonResult.success();
    }
    @Override
    public Employee finByIdNumber(String IdNumber) {
        LambdaQueryWrapper<Employee>wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getIdNumber,IdNumber);
        //查找这个身份证 如果返回有这个身份证或者null
        Employee res = employeeMapper.SelectByIdNumber(IdNumber);
        return res;
    }
    //这边写修改
    @Override
    public void update(Employee employee){
        // TODO: 2022/11/24   待开发2，姓名可以重复，身份证不能重复、用户名不能重复

        employee.setUpdateTime(LocalDateTime.now());
        employeeMapper.update(employee);
    }

}
